React Suspense ๋ฐ Error Boundaries: ๊ณ ๊ธ ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ | MLOG | MLOGํ๊ตญ์ด
๊ฐ๋ ฅํ ๋ก๋ฉ ์ํ ๊ด๋ฆฌ์ ์ฐ์ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ํด React Suspense ๋ฐ Error Boundaries๋ฅผ ๋ง์คํฐํ์ธ์. ํ๋ ฅ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
React Suspense ๋ฐ Error Boundaries: ๊ณ ๊ธ ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ
React Suspense ๋ฐ Error Boundaries๋ ๊ฐ๋ฐ์๊ฐ ๋ ํ๋ ฅ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์๋๋ก ํด์ฃผ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์
๋๋ค. ๋ก๋ฉ ์ํ์ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ ์ธ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ ๋ฐ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ๊ฐ๋ฐ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํฉ๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ๊ธฐ๋ณธ ๊ฐ๋
๋ถํฐ ๊ณ ๊ธ ๊ธฐ์ ๊น์ง ๋ชจ๋ ๊ฒ์ ๋ค๋ฃจ๋ฉด์ React Suspense ๋ฐ Error Boundaries๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
React Suspense ์ดํด
React Suspense๋ ์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ ์์
์ ๋ฐ์ดํฐ ๊ฐ์ฉ์ฑ๊ณผ ๊ฐ์ ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๊น์ง ์ปดํฌ๋ํธ ๋ ๋๋ง์ "์ผ์ ์ค์ง"ํ๋ ๋ฉ์ปค๋์ฆ์
๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๊ฐ ๋ก๋๋๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ์ ๊ฐ์ ๋์ฒด UI๋ฅผ ํ์ํ ์ ์์ต๋๋ค. Suspense๋ ์๋ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ์์ฑ์ ์์ ๊ณ ์ฝ๋ ๊ฐ๋
์ฑ์ ํฅ์์์ผ ๋ก๋ฉ ์ํ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํฉ๋๋ค.
Suspense์ ์ฃผ์ ๊ฐ๋
- Suspense Boundaries: ์ผ์ ์ค์ง๋ ์ ์๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ๋ React ์ปดํฌ๋ํธ์
๋๋ค. ๋ํ๋ ์ปดํฌ๋ํธ๊ฐ ์ผ์ ์ค์ง๋๋ ๋์ ํ์ํ ๋์ฒด UI๋ฅผ ์ ์ํฉ๋๋ค.
- Fallback UI: ์ปดํฌ๋ํธ๊ฐ ์ผ์ ์ค์ง๋๋ ๋์ ํ์๋๋ UI์
๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ก๋ฉ ํ์๊ธฐ ๋๋ ์๋ฆฌ ํ์์์
๋๋ค.
- ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ: Suspense๋ `fetch`, `axios` ๋๋ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฃจ์
๊ณผ ๊ฐ์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํํ๊ฒ ์๋ํฉ๋๋ค.
- ์ฝ๋ ๋ถํ : Suspense๋ ์ฝ๋ ๋ชจ๋ ๋ก๋ฉ์ ์ง์ฐ์ํค๋ ๋ฐ์๋ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์ฝ๋ ๋ถํ ์ ํ์ฑํํ๊ณ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
Suspense์ ๊ธฐ๋ณธ ๊ตฌํ
๋ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ธฐ ์ํด Suspense๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋จํ ์์
๋๋ค.
import React, { Suspense } from 'react';
// ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฎฌ๋ ์ด์
(์: API์์)
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ name: 'John Doe', age: 30 });
}, 2000);
});
};
// Suspense๊ฐ ์ฌ์ฉํ ์ ์๋ ๋ฆฌ์์ค ์์ฑ
const createResource = (promise) => {
let status = 'pending';
let result;
let suspender = promise().then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
}
);
return {
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
}
return result;
},
};
};
const userData = createResource(fetchData);
// ๋ฆฌ์์ค์์ ์ฝ๋ ์ปดํฌ๋ํธ
const UserProfile = () => {
const data = userData.read();
return (
Name: {data.name}
Age: {data.age}
);
};
const App = () => {
return (
์ฌ์ฉ์ ๋ฐ์ดํฐ ๋ก๋ฉ ์ค...
}>
);
};
export default App;
์ด ์์์:
- `fetchData`๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์์
์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค.
- `createResource`๋ ๋ฐ์ดํฐ์ ๋ก๋ฉ ์ํ๋ฅผ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋ฆฌ์์ค๋ฅผ ์์ฑํฉ๋๋ค.
- `UserProfile`์ `read` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค. ๋ฐ์ดํฐ๊ฐ ์์ง ์ฌ์ฉ ๊ฐ๋ฅํ์ง ์์ผ๋ฉด promise๋ฅผ throwํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ์ผ์ ์ค์งํฉ๋๋ค.
- `Suspense` ์ปดํฌ๋ํธ๋ `UserProfile`์ ๋ํํ๊ณ ์ปดํฌ๋ํธ๊ฐ ์ผ์ ์ค์ง๋๋ ๋์ ํ์ํ UI๋ฅผ ์ง์ ํ๋ `fallback` prop์ ์ ๊ณตํฉ๋๋ค.
์ฝ๋ ๋ถํ ์ ์ฌ์ฉํ Suspense
Suspense๋ React.lazy์ ํจ๊ป ์ฌ์ฉํ์ฌ ์ฝ๋ ๋ถํ ์ ๊ตฌํํ ์๋ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ์ํ ๊ฒฝ์ฐ์๋ง ์ปดํฌ๋ํธ๋ฅผ ๋ก๋ํ ์ ์์ผ๋ฏ๋ก ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์ฑ๋ฅ์ด ํฅ์๋ฉ๋๋ค.
import React, { Suspense, lazy } from 'react';
// MyComponent ์ปดํฌ๋ํธ๋ฅผ lazy ๋ก๋
const MyComponent = lazy(() => import('./MyComponent'));
const App = () => {
return (
์ปดํฌ๋ํธ ๋ก๋ฉ ์ค...
}>
);
};
export default App;
์ด ์์์:
- `React.lazy`๋ `MyComponent` ์ปดํฌ๋ํธ๋ฅผ ์ง์ฐ ๋ก๋ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- `Suspense` ์ปดํฌ๋ํธ๋ `MyComponent`๋ฅผ ๋ํํ๊ณ ์ปดํฌ๋ํธ๊ฐ ๋ก๋๋๋ ๋์ ํ์ํ UI๋ฅผ ์ง์ ํ๋ `fallback` prop์ ์ ๊ณตํฉ๋๋ค.
Error Boundaries ์ดํด
Error Boundaries๋ ํ์ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ JavaScript ์ค๋ฅ๋ฅผ ๋ชจ๋ catchํ๊ณ , ํด๋น ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ณ , ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ ์ค๋จํ๋ ๋์ ๋์ฒด UI๋ฅผ ํ์ํ๋ React ์ปดํฌ๋ํธ์
๋๋ค. ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ๋์ฑ ๊ฐ๋ ฅํ๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
Error Boundaries์ ์ฃผ์ ๊ฐ๋
- ์ค๋ฅ catch: Error Boundaries๋ ๋ ๋๋ง ์ค, ์๋ช
์ฃผ๊ธฐ ๋ฉ์๋์์, ๊ทธ๋ฆฌ๊ณ ํ์ ์ ์ฒด ํธ๋ฆฌ์ ์์ฑ์์์ ์ค๋ฅ๋ฅผ catchํฉ๋๋ค.
- Fallback UI: ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋ ํ์๋๋ UI์
๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ค๋ฅ ๋ฉ์์ง ๋๋ ์๋ฆฌ ํ์์์
๋๋ค.
- ์ค๋ฅ ๋ก๊น
: Error Boundaries๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๋ฅผ ๋๋ฒ๊น
๋ชฉ์ ์ผ๋ก ์๋น์ค ๋๋ ์ฝ์์ ๋ก๊น
ํ ์ ์์ต๋๋ค.
- ์ปดํฌ๋ํธ ํธ๋ฆฌ ๊ฒฉ๋ฆฌ: Error Boundaries๋ ์ค๋ฅ๋ฅผ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ํน์ ๋ถ๋ถ์ผ๋ก ๊ฒฉ๋ฆฌํ์ฌ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ด ์ค๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
Error Boundaries์ ๊ธฐ๋ณธ ๊ตฌํ
๋ค์์ Error Boundary๋ฅผ ๋ง๋๋ ๊ฐ๋จํ ์์
๋๋ค.
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// ๋ค์ ๋ ๋๋ง์์ ๋์ฒด UI๋ฅผ ํ์ํ๋๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// ์ค๋ฅ ๋ณด๊ณ ์๋น์ค์๋ ์ค๋ฅ๋ฅผ ๋ก๊น
ํ ์ ์์ต๋๋ค.
console.error(error, errorInfo);
}
render() {
if (this.state.hasError) {
// ๋ชจ๋ ์ฌ์ฉ์ ์ง์ ๋์ฒด UI๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค.
return ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
;
}
return this.props.children;
}
}
export default ErrorBoundary;
์ด ์์์:
- `ErrorBoundary` ์ปดํฌ๋ํธ๋ `getDerivedStateFromError` ๋ฐ `componentDidCatch` ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค.
- `getDerivedStateFromError`๋ ํ์ ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๋ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ์์ ๋ํ๋ด๋๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
- `componentDidCatch`๋ ์ค๋ฅ๊ฐ catch๋ ํ์ ํธ์ถ๋ฉ๋๋ค. ์๋น์ค ๋๋ ์ฝ์์ ์ค๋ฅ๋ฅผ ๋ก๊น
ํ ์ ์์ต๋๋ค.
- `render` ๋ฉ์๋๋ `hasError` ์ํ๋ฅผ ํ์ธํ๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค.
Error Boundaries ์ฌ์ฉ
`ErrorBoundary` ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ณดํธํ๋ ค๋ ์ปดํฌ๋ํธ๋ฅผ ํด๋น ์ปดํฌ๋ํธ๋ก ๋ํํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
const MyComponent = () => {
// ์ค๋ฅ ์๋ฎฌ๋ ์ด์
throw new Error('์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค!');
};
const App = () => {
return (
);
};
export default App;
์ด ์์์ `MyComponent`์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด `ErrorBoundary` ์ปดํฌ๋ํธ๊ฐ ์ค๋ฅ๋ฅผ catchํ๊ณ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค.
Suspense ๋ฐ Error Boundaries ๊ฒฐํฉ
Suspense ๋ฐ Error Boundaries๋ฅผ ๊ฒฐํฉํ์ฌ ๋น๋๊ธฐ ์์
์ ๋ํ ๊ฐ๋ ฅํ๊ณ ํฌ๊ด์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ์ ๋ต์ ์ ๊ณตํ ์ ์์ต๋๋ค. Suspense๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํ๊ณ Error Boundaries๋ฅผ ์ฌ์ฉํ์ฌ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํจ์ผ๋ก์จ ๋ก๋ฉ ์ํ์ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ๋ชจ๋ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
Suspense ๋ฐ Error Boundaries ๊ฒฐํฉ์ ์
import React, { Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';
// ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฎฌ๋ ์ด์
(์: API์์)
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// ์ฑ๊ณต์ ์ธ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฎฌ๋ ์ด์
// resolve({ name: 'John Doe', age: 30 });
// ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๋ ๋์ ์ค๋ฅ ์๋ฎฌ๋ ์ด์
reject(new Error('์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค์ง ๋ชปํ์ต๋๋ค'));
}, 2000);
});
};
// Suspense๊ฐ ์ฌ์ฉํ ์ ์๋ ๋ฆฌ์์ค ์์ฑ
const createResource = (promise) => {
let status = 'pending';
let result;
let suspender = promise().then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
}
);
return {
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
}
return result;
},
};
};
const userData = createResource(fetchData);
// ๋ฆฌ์์ค์์ ์ฝ๋ ์ปดํฌ๋ํธ
const UserProfile = () => {
const data = userData.read();
return (
Name: {data.name}
Age: {data.age}
);
};
const App = () => {
return (
์ฌ์ฉ์ ๋ฐ์ดํฐ ๋ก๋ฉ ์ค...}>
);
};
export default App;
์ด ์์์:
- `ErrorBoundary` ์ปดํฌ๋ํธ๋ `Suspense` ์ปดํฌ๋ํธ๋ฅผ ๋ํํฉ๋๋ค.
- `Suspense` ์ปดํฌ๋ํธ๋ `UserProfile` ์ปดํฌ๋ํธ๋ฅผ ๋ํํฉ๋๋ค.
- `fetchData` ํจ์๊ฐ ์ค๋ฅ๋ก reject๋๋ฉด `Suspense` ์ปดํฌ๋ํธ๊ฐ promise reject๋ฅผ catchํ๊ณ `ErrorBoundary`๊ฐ Suspense์์ throw๋ ์ค๋ฅ๋ฅผ catchํฉ๋๋ค.
- ๊ทธ๋ฌ๋ฉด `ErrorBoundary`๊ฐ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค.
- ๋ฐ์ดํฐ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์ค๋ฉด `Suspense` ์ปดํฌ๋ํธ๊ฐ `UserProfile` ์ปดํฌ๋ํธ๋ฅผ ํ์ํฉ๋๋ค.
๊ณ ๊ธ ๊ธฐ์ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
Suspense ์ฑ๋ฅ ์ต์ ํ
- ๋ฉ๋ชจ์ด์ ์ด์
์ฌ์ฉ: ๋ถํ์ํ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํ๊ธฐ ์ํด Suspense ๊ฒฝ๊ณ ๋ด์์ ๋ ๋๋ง๋๋ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
ํฉ๋๋ค.
- ๊น์ Suspense ํธ๋ฆฌ ๋ฐฉ์ง: ๋ ๋๋ง ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ์ต์ํํ๊ธฐ ์ํด Suspense ํธ๋ฆฌ๋ฅผ ์๊ฒ ์ ์งํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์ค๊ธฐ: ์ผ์ ์ค๋จ ๊ฐ๋ฅ์ฑ์ ์ค์ด๊ธฐ ์ํด ํ์ํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์ต๋๋ค.
์ฌ์ฉ์ ์ง์ Error Boundaries
ํน์ ์ ํ์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ฑฐ๋ ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ์ฉ์ ์ง์ Error Boundaries๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ํ ์ค๋ฅ ์ ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋์ฒด UI๋ฅผ ํ์ํ๋ Error Boundary๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
Suspense๋ฅผ ์ฌ์ฉํ ์๋ฒ ์ธก ๋ ๋๋ง(SSR)
์ด๊ธฐ ํ์ด์ง ๋ก๋ ์ฑ๋ฅ์ ๊ฐ์ ํ๊ธฐ ์ํด Suspense๋ฅผ ์๋ฒ ์ธก ๋ ๋๋ง(SSR)๊ณผ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค. SSR์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์๋ฒ์์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ด๊ธฐ ์ํ๋ฅผ ๋ฏธ๋ฆฌ ๋ ๋๋งํ ๋ค์ ๋๋จธ์ง ์ฝํ
์ธ ๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์คํธ๋ฆฌ๋ฐํ ์ ์์ต๋๋ค. Suspense๋ฅผ ์ฌ์ฉํ๋ฉด SSR ์ค์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆฌ๋ฐํ๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
๋ค์ํ ์ค๋ฅ ์๋๋ฆฌ์ค ์ฒ๋ฆฌ
๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์ค๋ฅ ์๋๋ฆฌ์ค์ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ์ญ์์ค.
- ๋คํธ์ํฌ ์ค๋ฅ: ์ฌ์ฉ์์๊ฒ ์ ์ตํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ์ฌ ๋คํธ์ํฌ ์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
- API ์ค๋ฅ: ๋ฐ์ํ ์ค๋ฅ์ ํน์ ๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ์ฌ API ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- ์์์น ๋ชปํ ์ค๋ฅ: ์ค๋ฅ๋ฅผ ๋ก๊น
ํ๊ณ ์ฌ์ฉ์์๊ฒ ์ผ๋ฐ์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ์ฌ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
์ ์ญ ์ค๋ฅ ์ฒ๋ฆฌ
Error Boundaries์์ catch๋์ง ์์ ์ค๋ฅ๋ฅผ catchํ๊ธฐ ์ํด ์ ์ญ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํฉ๋๋ค. ์ด๋ ์ ์ญ ์ค๋ฅ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ Error Boundary๋ก ๋ํํ์ฌ ์ํํ ์ ์์ต๋๋ค.
์ค์ ์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
์ ์ ์๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ ์๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์
์์ Suspense๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ณ Error Boundaries๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ์ ํ๋ก์ธ์ค ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ฏธ๊ตญ์ ์์นํ ์จ๋ผ์ธ ์์ ์ ํ์ํ๋ ์ผ๋ณธ์ ์ฌ์ฉ์๋ฅผ ์์ํด ๋ณด์ญ์์ค. ์ ํ ์ด๋ฏธ์ง์ ์ค๋ช
์ด ๋ก๋๋๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค. Suspense๋ ์ด ๋ฐ์ดํฐ๊ฐ ์ ์ธ๊ณ ์๋ฒ์์ ๊ฐ์ ธ์ค๋ ๋์ ๊ฐ๋จํ ๋ก๋ฉ ์ ๋๋ฉ์ด์
์ ํ์ํ ์ ์์ต๋๋ค. ๊ฒฐ์ ๊ฒ์ดํธ์จ์ด๊ฐ ์ผ์์ ์ธ ๋คํธ์ํฌ ๋ฌธ์ (์ ์ธ๊ณ์ ์ผ๋ก ๋ค์ํ ์ธํฐ๋ท ์ธํ๋ผ์์ ํํจ)๋ก ์ธํด ์คํจํ๋ฉด Error Boundary๊ฐ ๋์ค์ ๋ค์ ์๋ํ๋ผ๋ ๋ฉ์์ง๋ฅผ ํ์ํ์ฌ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฉ์์ง๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
์์
๋ฏธ๋์ด ํ๋ซํผ
์์
๋ฏธ๋์ด ํ๋ซํผ์์ Suspense๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ํ๋กํ ๋ฐ ๊ฒ์๋ฌผ์ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ณ Error Boundaries๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง ๋๋ ๋น๋์ค๋ฅผ ๋ก๋ํ ๋ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ธ๋์์ ํ์ํ๋ ์ฌ์ฉ์๊ฐ ์ ๋ฝ์ ์๋ฒ์ ํธ์คํ
๋ ๋ฏธ๋์ด๋ฅผ ๋ก๋ํ๋ ๋ฐ ์๊ฐ์ด ๋ ์ค๋ ๊ฑธ๋ฆด ์ ์์ต๋๋ค. Suspense๋ ์ฝํ
์ธ ๊ฐ ์์ ํ ๋ก๋๋ ๋๊น์ง ์๋ฆฌ ํ์์๋ฅผ ํ์ํ ์ ์์ต๋๋ค. ํน์ ์ฌ์ฉ์์ ํ๋กํ ๋ฐ์ดํฐ๊ฐ ์์๋ ๊ฒฝ์ฐ(๋๋ฌผ์ง๋ง ๊ฐ๋ฅํจ) Error Boundary๊ฐ ์ ์ฒด ์์
๋ฏธ๋์ด ํผ๋๊ฐ ์ค๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ "์ฌ์ฉ์ ํ๋กํ์ ๋ก๋ํ ์ ์์ต๋๋ค"์ ๊ฐ์ ๊ฐ๋จํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
๋์๋ณด๋ ์ ํ๋ฆฌ์ผ์ด์
๋์๋ณด๋ ์ ํ๋ฆฌ์ผ์ด์
์์ Suspense๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ์์ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ณ Error Boundaries๋ฅผ ์ฌ์ฉํ์ฌ ์ฐจํธ ๋๋ ๊ทธ๋ํ๋ฅผ ๋ก๋ํ ๋ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ฐ๋์ ์๋ ๊ธ์ต ๋ถ์๊ฐ๊ฐ ์ ์ธ๊ณ ์ฌ๋ฌ ๊ฑฐ๋์์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ๊ธ๋ก๋ฒ ํฌ์ ๋์๋ณด๋์ ์ก์ธ์คํ๊ณ ์์ ์ ์์ต๋๋ค. Suspense๋ ๊ฐ ๋ฐ์ดํฐ ์์ค์ ๋ํ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ํ ๊ฑฐ๋์์ API๊ฐ ๋ค์ด๋ ๊ฒฝ์ฐ Error Boundary๊ฐ ํด๋น ๊ฑฐ๋์์ ๋ฐ์ดํฐ์ ๋ํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ์ฌ ์ ์ฒด ๋์๋ณด๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
React Suspense ๋ฐ Error Boundaries๋ ํ๋ ฅ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ React ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๊ธฐ ์ํ ํ์ ๋๊ตฌ์
๋๋ค. Suspense๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ Error Boundaries๋ฅผ ์ฌ์ฉํ์ฌ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ฉด ์ ๋ฐ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ๊ฐ๋ฐ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์๋ ๊ธฐ๋ณธ ๊ฐ๋
๋ถํฐ ๊ณ ๊ธ ๊ธฐ์ ๊น์ง ๋ชจ๋ ๊ฒ์ ๋ค๋ฃจ๋ฉด์ Suspense ๋ฐ Error Boundaries์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์๋ฅผ ์ ๊ณตํ์ต๋๋ค. ์ด ๊ธฐ์ฌ์์ ์ค๋ช
ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด ๊ฐ์ฅ ์ด๋ ค์ด ์๋๋ฆฌ์ค์์๋ ์ฒ๋ฆฌํ ์ ์๋ ๊ฐ๋ ฅํ๊ณ ์์ ์ ์ธ React ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
React๊ฐ ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ Suspense ๋ฐ Error Boundaries๋ ์ต์ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐ ์ ์ ๋ ์ค์ํ ์ญํ ์ ํ ๊ฒ์
๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ๋ง์คํฐํ๋ฉด ์์ ๋๊ฐ ํ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.